home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archivers / XpkDisk / magic.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  6KB  |  235 lines

  1. /*-
  2.  * MAGIC.C
  3.  *
  4.  * The xpkdisk.device code that looks into DOS data structures.
  5.  *
  6.  * $Id: magic.c,v 1.5 1995/04/08 20:21:52 Rhialto Exp $
  7.  * $Log: magic.c,v $
  8.  * Revision 1.5  1995/04/08  20:21:52  Rhialto
  9.  * Add/correct version strings.
  10.  *
  11.  * Revision 1.4  1995/04/02  14:58:51  Rhialto
  12.  * Change #ifdef into #if.
  13.  * Update for DICE 3.0. Lots more casts.
  14.  *
  15.  * Revision 1.3  1993/11/08  13:11:15  Rhialto
  16.  * Add RCS tags.
  17.  *
  18.  *
  19.  * This code is (C) Copyright 1993,1994 by Olaf Seibert. All rights reserved.
  20.  * May not be used or copied without a licence.
  21. -*/
  22.  
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include "xpkdisk.h"
  27. #ifndef LIBRARIES_FILEHANDLER_H
  28. #include <libraries/filehandler.h>
  29. #endif
  30.  
  31. /*#undef DEBUG      /**/
  32. #if DEBUG
  33. #   include "syslog.h"
  34. #else
  35. #   define    debug(x)
  36. #endif
  37.  
  38. static const char rcsId[] = "$Id: magic.c,v 1.5 1995/04/08 20:21:52 Rhialto Exp $";
  39.  
  40. extern struct DosLibrary *DOSBase;
  41.  
  42. int
  43. FileNamesMatch(char *path, char *name)
  44. {
  45.     char       *s;
  46.  
  47.     if (s = strchr(path, ':'))
  48.     path = s + 1;
  49.     if (s = strrchr(path, '/'))
  50.     path = s + 1;
  51.     return !strcmp(path, name);
  52. }
  53.  
  54. /*
  55.  * Try to get the DosEnvec values from the mountlist. This is quite a
  56.  * work!
  57.  * We must be reasonable sure that the dn_Startup fields both refer
  58.  * to a FileSysStarupMsg. They must both be pointers (and not some
  59.  * small integral values, as used to distinguish CON and RAW, for
  60.  * example).
  61.  */
  62.  
  63. struct DosEnvec *
  64. IsOurDevicenode(UNIT *unit, struct DeviceNode *dn)
  65. {
  66.     struct FileSysStartupMsg *dnmsg;
  67.  
  68.     if (dn->dn_Type != DLT_DEVICE)
  69.     return NULL;
  70.  
  71. #if DEBUG
  72.     {
  73.     char *s = BADDR(dn->dn_Name);
  74.     debug(("%.*s:\n", *s, s + 1));
  75.     }
  76. #endif
  77.     dnmsg = BADDR(dn->dn_Startup);
  78.     debug(("Startup: %x, '%.20s' %d\n", dnmsg,
  79.     (char *)BADDR(dnmsg->fssm_Device) + 1,
  80.     dnmsg->fssm_Unit ));
  81.     if (dnmsg &&
  82.     (long)dnmsg > 4*100 &&
  83.     dnmsg->fssm_Device &&
  84.     FileNamesMatch((char *)BADDR(dnmsg->fssm_Device) + 1, DevName) &&
  85.     dnmsg->fssm_Unit == unit->xu_UnitNr
  86.     ) {
  87.     long           *dnenv = BADDR(dnmsg->fssm_Environ);
  88.  
  89.     /* actually struct DosEnvec */
  90.     debug(("Environ: %x\n", dnenv));
  91.  
  92.     if (dnenv && dnenv[0] >= DE_DOSTYPE) {
  93.         debug(("Found our mount information at %lx, %lx!\n", dn, dnenv));
  94.         return (struct DosEnvec *)dnenv;
  95.     }
  96.     }
  97.     return NULL;
  98. }
  99.  
  100. void
  101. MagicInitDevicenode(UNIT *unit)
  102. {
  103.     struct RootNode *rn = (struct RootNode *) DOSBase->dl_Root;
  104.     struct DosInfo *DosInfo = (struct DosInfo *) BADDR(rn->rn_Info);
  105.     struct DeviceNode *dn = BADDR(DosInfo->di_DevInfo);
  106.  
  107.     debug(("traverse_bcpl: %x\n", dn));
  108.     while (dn) {
  109.     struct DosEnvec *de;
  110.  
  111.     if (de = IsOurDevicenode(unit, dn)) {
  112.         unit->xu_NumTracks = de->de_Surfaces * (de->de_HighCyl + 1);
  113.         unit->xu_TrackLen = 4 * de->de_SizeBlock * de->de_BlocksPerTrack;
  114.         debug(("numtracks %d tracklen %d\n",
  115.            unit->xu_NumTracks, unit->xu_TrackLen));
  116. #if 0
  117.         /* Hackery: */
  118.         debug(("tablesize %d CONTROL=%d\n", de->de_TableSize, DE_CONTROL));
  119.         if (de->de_TableSize >= DE_CONTROL) {
  120.         debug(("string %x: %.20s\n", de->de_Control, de->de_Control));
  121.         }
  122. #endif
  123.         return;
  124.     }
  125.  
  126.     dn = BADDR(dn->dn_Next);
  127.     debug(("traverse_bcpl: next is %x\n", dn));
  128.     }
  129. }
  130.  
  131. #define ON(d,s)     ((d) |= (s))
  132. #define OFF(d,s)    ((d) &= ~(s))
  133.  
  134. ulong
  135. Flag(char *opt, char *name, ulong mask, ulong previous)
  136. {
  137.     char *match;
  138.  
  139.     if (match = strstr(opt, name)) {
  140.     int o = 1;
  141.     int l = strlen(name);
  142.  
  143.     debug(("Flag: %s\n", match));
  144.     if (match[l] == '=')
  145.         o = strtol(match + l + 1, NULL, 0);
  146.     if (o)
  147.         previous |= mask;
  148.     else
  149.         previous &= ~mask;
  150.     }
  151.     return previous;
  152. }
  153.  
  154. void
  155. ParseOptions(UNIT *unit, char *opt)
  156. {
  157.     ulong        f;
  158.     char       *value;
  159.  
  160.     debug(("ParseOptions: %s\n", opt));
  161.  
  162.     if (value = strstr(opt, S_XPKPackMethod "=")) {
  163. #define SZ sizeof(unit->xu_XPKPackMethod)
  164.     int        len;
  165.  
  166.     value += sizeof(S_XPKPackMethod);
  167.     len = strcspn(value, " \t\n,;=");
  168.     len = min(len, SZ-1);
  169.     debug(("Match "S_XPKPackMethod"='%s', len %d\n", value, len));
  170.     strncpy(unit->xu_XPKPackMethod, value, len);
  171.     unit->xu_XPKPackMethod[len] = '\0';
  172.     debug(("PackMethod now %s\n", unit->xu_XPKPackMethod));
  173.     } else
  174.     debug(("Don't match "S_XPKPackMethod"=\n"));
  175.     if (value = strstr(opt, S_MaxCache "=")) {
  176.     unit->xu_MaxCache = strtol(value + sizeof(S_MaxCache), NULL, 0);
  177.     debug(("Match "S_MaxCache "='%d'\n", unit->xu_MaxCache));
  178.     }
  179.     if (value = strstr(opt, S_CacheTimeout "=")) {
  180.     unit->xu_CacheTimeout = strtol(value + sizeof(S_CacheTimeout), NULL, 0);
  181.     debug(("Match "S_CacheTimeout "='%d'\n", unit->xu_CacheTimeout));
  182.     }
  183.     f = unit->xu_CacheFlags;
  184.     f = Flag(opt, S_CMDUPDATE, CACHEF_CMDUPDATE, f);
  185.     f = Flag(opt, S_DELAY, CACHEF_DELAY, f);
  186.     f = Flag(opt, S_SAFEWRITE, CACHEF_SAFEWRITE, f);
  187.     f = Flag(opt, S_LICENSED, CACHEF_LICENSED, f);
  188.     unit->xu_CacheFlags = f;
  189. }
  190.  
  191. int
  192. ReadConfig(UNIT *unit, char *buf, int sz)
  193. {
  194.     BPTR        fh;
  195.  
  196.     fh = Open(buf, MODE_OLDFILE);
  197.     if (fh) {
  198.     int        len;
  199.  
  200.     len = Read(fh, buf, sz-1);
  201.     Close(fh);
  202.     if (len >= 0) {
  203.         buf[len] = 0;
  204.         ParseOptions(unit, buf);
  205.  
  206.         return 1;
  207.     }
  208.     }
  209.     return 0;
  210. }
  211.  
  212. /*
  213.  * First get the permanent settings, then overwrite with the
  214.  * temporary ones.
  215.  */
  216.  
  217. void
  218. MagicInitFile(UNIT *unit)
  219. {
  220.     char        buf[128];
  221.  
  222.     sprintf(buf, CONFIGFILE_ARC, unit->xu_UnitNr);
  223.     ReadConfig(unit, buf, sizeof(buf));
  224.     sprintf(buf, CONFIGFILE, unit->xu_UnitNr);
  225.     ReadConfig(unit, buf, sizeof(buf));
  226. }
  227.  
  228. Prototype void MagicInit(UNIT *unit);
  229. void
  230. MagicInit(UNIT *unit)
  231. {
  232.     MagicInitDevicenode(unit);
  233.     MagicInitFile(unit);
  234. }
  235.